package com.lifp.thread.synchronize;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description 多线程加减法测试
 *
 *     多线程实现 +1 或 -1操作
 *
 *
 * @Author lfp
 * @Date 2022/7/24
 * @Version 1.0
 */

//第一步 创建资源类，定义属性和操作方法
@Slf4j
class Share {
    private int number = 0;

    /**
     * +1方法
     */
    @SneakyThrows
    public synchronized void increase(){
        //第二步 判断、执行操作、通知

        //必须把条件放在循环中，防止虚假唤醒操作
        while (number != 0){
            //object.wait()会释放锁，并且在哪里等待，就在哪里唤醒
            this.wait();
        }

        //如果当前线程抢到了锁，且满足条件，执行方法
        number ++;

        this.notifyAll();//通知其他线程

        log.info("线程：{}，完成了increase,值为：{}",Thread.currentThread().getName(),number);
    }

    /**
     * -1方法
     */
    @SneakyThrows
    public synchronized void decrease(){
        //必须把条件放在循环中，防止虚假唤醒操作
        while (number != 1){
            this.wait();
        }

        //如果当前线程抢到了锁，且满足条件，执行方法
        number --;

        this.notifyAll();//通知其他线程

        log.info("线程：{}，完成了increase,值为：{}",Thread.currentThread().getName(),number);
    }
}

@Slf4j
public class SynchronizedIncreaseOrDecrease {
    //第三步 创建多个线程，
    public static void main(String[] args) {
        Share share = new Share();

        //通过内部类的形式，创建线程AA
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    share.increase();//+1
                }
            }
        },"AA").start();

        //通过lambda 表达式的形式，创建线程BB，执行-1 操作
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                share.decrease();//-1
            }
        },"BB").start();

        //创建线程CC，执行+1 操作
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                share.increase();//+1
            }
        },"CC").start();

        //创建线程DD，执行-1 操作
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                share.decrease();//-1
            }
        },"DD").start();
    }
}

